/******************************************************************************
 * Copyright 2022 The Airos Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include <memory>
#include <thread>
#include <chrono>

#include <glog/logging.h>

#include "framework/msg.h"
#include "framework/actor.h"
#include "framework/worker.h"

class @template_name@Actor : public air::link::Actor {
 public:
  int Init(const char* param) override {
    return 0;
  }

  void Proc(const std::shared_ptr<const air::link::Msg>& msg) override {
    /// 获得消息， 打印 源地址 目的地址 消息内容
    LOG(INFO) << GetActorName() << ":";
    LOG(INFO) << "--> msg from \"" << msg->GetSrc() << ": " << msg->GetData();
  }
};

class @template_name@Receiver : public air::link::Worker {
 public:
  @template_name@Receiver() {}
  virtual ~@template_name@Receiver() {}

  void OnInit() override {
    /// 初始化接收数据模块
    /// ...
  }

  /// airos-vehicle会循环调用该函数
  void Run() override {
    std::string data;
    /// TODO here 阻塞接收数据
    /// ...
    std::this_thread::sleep_for(std::chrono::seconds(1));

    /// 发送数据给airos-vehicle中的某个模块
    auto msg = std::make_shared<air::link::Msg>();
    msg->SetData(data);
    /// TODO here 设置要发送的目的模块名
    /// eg: SendMsg("actor.xx.xx", msg);
    /// ...

    /// 分发消息
    DispatchMsg();
  }
};

class @template_name@Sender : public air::link::Worker {
 public:
  @template_name@Sender() {}
  virtual ~@template_name@Sender() {}

  void OnInit() override {
    /// 初始化发送数据模块
  }

  /// airos-vehicle会循环调用该函数
  void Run() override {
    /// 等待airos-vehicle数据
    DispatchAndWaitMsg();
    while (RecvMsgListSize() > 0) {
      const auto& msg = GetRecvMsg();
      /// TODO here 将airos-vehicle数据发送出去
      /// ...
    }
  }
};

/* 创建actor实例函数 */
extern "C" std::shared_ptr<air::link::Actor> actor_create(
    const std::string& actor_name) {
  if (actor_name == "@template_name@Actor") {
    return std::make_shared<@template_name@Actor>();
  }
  return nullptr;
}

/* 创建worker实例函数 */
extern "C" std::shared_ptr<air::link::Worker> worker_create(
    const std::string& worker_name) {
  if (worker_name == "@template_name@Receiver") {
    return std::make_shared<@template_name@Receiver>();
  }
  if (worker_name == "@template_name@Sender") {
    return std::make_shared<@template_name@Sender>();
  }
  return nullptr;
}
